package com.example.tangyee.utils;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.example.tangyee.R;
import com.example.tangyee.bean.BloodGlucoseRecord;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class BloodGlucoseDataUtil {

    private static final String TAG = "BloodGlucoseDataUtil";

    private GetBloodGlucoseData getBloodGlucoseData;
    private SaveBloodGlucoseData saveBloodGlucoseData;

    public void clear() {
        if (getBloodGlucoseData != null) {
            getBloodGlucoseData.cancel(true);
        }
        if (saveBloodGlucoseData != null) {
            saveBloodGlucoseData.cancel(true);
        }
    }

    public GetBloodGlucoseData getBloodGlucoseData(Context context, int days, OnPostExecute execute) {
        if (getBloodGlucoseData != null) {
            getBloodGlucoseData.cancel(true);
        }
        getBloodGlucoseData = new GetBloodGlucoseData(context, days, execute);
        getBloodGlucoseData.execute();
        return getBloodGlucoseData;
    }

    public SaveBloodGlucoseData saveBloodGlucoseData(Context context, BloodGlucoseRecord bloodGlucoseRecord, int sign, double data, OnPostExecute execute) {
        if (saveBloodGlucoseData != null) {
            saveBloodGlucoseData.cancel(true);
        }
        saveBloodGlucoseData = new SaveBloodGlucoseData(context, bloodGlucoseRecord, sign, data, execute);
        saveBloodGlucoseData.execute();
        return saveBloodGlucoseData;
    }

    private class GetBloodGlucoseData extends AsyncTask<Void, Void, List<BloodGlucoseRecord>> {

        private int days;
        private Context mContext;
        private OnPostExecute mOnPostExecute;

        public GetBloodGlucoseData(Context context, int days, OnPostExecute execute) {
            this.days = days;
            this.mContext = context;
            this.mOnPostExecute = execute;
        }

        @Override
        protected List<BloodGlucoseRecord> doInBackground(Void... voids) {
            String respStr = null;
            if (isCancelled()) {
                return null;
            }
            SessionidUtils.updateSessionId(mContext);

            OkHttpClient okHttpClient = new OkHttpClient();

            RequestBody body = new FormBody.Builder()
                    .add("rDay", String.valueOf(days))
                    .build();

            Request request = new Request.Builder()
                    .url(ConstantsUtil.GET_BLOOD_GLUCOSE_DATA)
                    .addHeader("cookie", SessionidUtils.getCookie(mContext))
                    .post(body)
                    .build();

            try {
                Response response = okHttpClient.newCall(request).execute();
                if (response.isSuccessful()) {
                    respStr = response.body().string();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            List<BloodGlucoseRecord> items = new ArrayList<>();

            try {
                Log.i(TAG, "Received JSON: " + respStr);
                if (respStr == null) {
                    return null;
                }
                JSONArray jsonArray = new JSONArray(respStr);

                // 将json转成list
                parseItems(items, jsonArray);
            } catch (JSONException je) {
                Log.e(TAG, "Failed to parse JSON", je);
                return null;
            }

            List<BloodGlucoseRecord> list = new ArrayList<>();
            Date date = new Date();
            date.setHours(0);
            date.setMinutes(0);
            date.setSeconds(0);
            Log.d(TAG, "doInBackground: " + date.getTime() + "|" + date);
            for (int i = 0; i < days; i ++) {
                Date d = DateUtils.getPreDate(date, i);
                boolean isAdd = false;
                for (int j = 0; j < items.size(); j ++) {
                    BloodGlucoseRecord bgr = items.get(j);
                    if (DateUtils.isSameDay(d, bgr.getRecordDate())) {
                        list.add(bgr);
                        isAdd = true;
                        break;
                    }
                }
                if (isAdd) {
                    continue;
                } else {
                    BloodGlucoseRecord bloodGlucoseRecord = new BloodGlucoseRecord();
                    bloodGlucoseRecord.setRecordDate(d);
                    list.add(bloodGlucoseRecord);
                }
            }

            return list;
        }

        @Override
        protected void onPostExecute(List<BloodGlucoseRecord> bloodGlucoseRecords) {
            if (mOnPostExecute != null) {
                mOnPostExecute.onPostExecute(bloodGlucoseRecords);
            }
        }
    }

    public interface OnPostExecute<T> {
        void onPostExecute(T result);
    }

    private class SaveBloodGlucoseData extends AsyncTask<Void, Void, String> {

        private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.CHINA);
        private BloodGlucoseRecord mBloodGlucoseRecord;
        private int sign;
        private double data;
        private Context mContext;
        private OnPostExecute<String> mExecute;

        SaveBloodGlucoseData(Context context, BloodGlucoseRecord bloodGlucoseRecord, int sign, double data, OnPostExecute<String> execute) {
            this.mBloodGlucoseRecord = bloodGlucoseRecord;
            this.sign = sign;
            this.data = data;
            this.mContext = context;
            this.mExecute = execute;
        }

        @Override
        protected String doInBackground(Void... voids) {
            if (isCancelled()) {
                return null;
            }
            SessionidUtils.updateSessionId(mContext);
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .retryOnConnectionFailure(false)
                    .build();

            RequestBody body = new FormBody.Builder()
                    .add("recordDate",  dateFormat.format(mBloodGlucoseRecord.getRecordDate()))
                    .add("timePoint", DateUtils.getTimeDescriptionEn(sign))
                    .add("mValue", String.format(Locale.CHINA, "%.1f", data))
                    .build();
            Request request = new Request.Builder()
                    .url(ConstantsUtil.SET_BLOOD_GLUCOSE_DATA)
                    .addHeader("cookie", SessionidUtils.getCookie(mContext))
                    .post(body)
                    .build();

            try {
                Response response = okHttpClient.newCall(request).execute();
                return response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            Log.i(TAG, "Received JSON: " + s);
            if (mExecute != null) {
                mExecute.onPostExecute(s);
            }
        }
    }


    private void parseItems(List<BloodGlucoseRecord> items, JSONArray jsonArray) {
        for (int i = 0; i < jsonArray.length(); i ++) {
            JSONObject jsonObject;
            BloodGlucoseRecord bloodGlucoseRecord = new BloodGlucoseRecord();
            try {
                jsonObject = jsonArray.getJSONObject(i);

                bloodGlucoseRecord.setId(jsonObject.getInt("ID"));
                bloodGlucoseRecord.setUserId(jsonObject.getInt("UserId"));

                for (int j = 1; j < 9; j ++) {
                    String str = jsonObject.getString(DateUtils.getTimeDescriptionEn(j));
                    double d = 0;
                    try {
                        d = Double.parseDouble(str);
                    } catch (NumberFormatException nfe) {
                        Log.d(TAG, "parseItems: " + nfe.getMessage());
                    }
                    bloodGlucoseRecord.setDataBySign(j, d);
                }
                String d = jsonObject.getString("RecordDate");
                d = d.substring(6, d.length() - 2);
                long dd = Long.parseLong(d);
                Date date = new Date(dd);
                bloodGlucoseRecord.setRecordDate(date);
            } catch (JSONException e) {
                Log.e(TAG, "parseItems: ", e);
            }
            items.add(bloodGlucoseRecord);
        }
    }

}

